package br.com.documentos.model.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetails;

import br.com.documentos.model.entity.Usuario;
import br.com.documentos.model.exceptions.AutenticacaoInvalidaException;
import br.com.documentos.model.exceptions.UsuarioBloqueadoException;
import br.com.documentos.model.exceptions.UsuarioInativoException;
import br.com.documentos.model.util.CriptografiaUtil;
import br.com.documentos.model.util.StringUtil;
import br.com.documentos.model.vo.UsuarioAuthentication;

public class AutenticacaoService extends AbstractUserDetailsAuthenticationProvider {

	@Autowired
	private UsuarioService usuarioService;
	
	protected UserDetails retrieveUser(String email,UsernamePasswordAuthenticationToken password)
			throws AuthenticationException {
		
		email = email.toLowerCase().trim();
		String senha = password.getCredentials().toString();
		
		if( StringUtil.isNotEmpty(email) && StringUtil.isNotEmpty(senha) )
		{
			Usuario usuario = usuarioService.buscarPorEmail(email);
			
			if( usuario != null )
			{
				String ip = ((WebAuthenticationDetails)password.getDetails()).getRemoteAddress();
				
				if( usuarioService.limiteTentativaAcessoExcedido(usuario.getId(), ip) ){
					throw new UsuarioBloqueadoException();
				}
				
				senha = CriptografiaUtil.encriptarMD5(senha);
				
				if( usuario.getSenha().equals(senha) )
				{
					if( usuario.isAtivo() ){
						usuarioService.adicionarTentativaAcesso(usuario.getId(), ip, true);
						return new UsuarioAuthentication(usuario);
					}
					else {
						throw new UsuarioInativoException();
					}
				}
				else {
					usuarioService.adicionarTentativaAcesso(usuario.getId(), ip, false);
					throw new AutenticacaoInvalidaException();
				}
			}
			else {
				throw new AutenticacaoInvalidaException();
			}
		}
		else {
			throw new AutenticacaoInvalidaException();
		}
	}
		
	protected void additionalAuthenticationChecks(UserDetails userDetails,	UsernamePasswordAuthenticationToken authenticationToken)
			throws AuthenticationException {
	}

}
